package au.org.arcs.dss.provider.util;

import java.util.*;
import java.io.*;

import org.springframework.core.io.Resource;
import au.org.arcs.dss.provider.ConfigManager;

/**
 *
 * @author ming
 */
public class SystemUtils {
  private static final String LIST_SUFFIX = "#List#";
  private static String PREFIX_TEMP = "temp";

  /**
   * Remove '/' or '\' at the end of the path.
   */
  public static String normalizePath(String path) {
    if (path != null && !path.isEmpty()) {
      if (path.endsWith("/") || path.endsWith("\\")) {
        path = path.substring(0, path.length() - 1);
      }
    }

    return path;
  }

  /**
   * Remove '/' or '\' at the beginning of the name.
   */
  public static String normalizeName(String name) {
    if (name != null && !name.isEmpty()) {
      if (name.startsWith("/") || name.startsWith("\\")) {
        name = name.substring(0, name.length() - 1);
      }
    }

    return name;
  }

  /**
   * Helper method to create an unique key string in cache Element.
   * @return
   */
  public static String getCacheKey(String path, String name, boolean isList) {
    if (name != null && !name.isEmpty()) {
      path = path + '/' + name;
    }

    if (isList) {
      path = path + LIST_SUFFIX;
    }

    return path;
  }

  public static String removeListSuffix(String key) {
    if (key.endsWith(LIST_SUFFIX)) {
      return key.substring(0, key.length() - LIST_SUFFIX.length());
    }

    return key;
  }

  public static InputStream getConfigWithSubstitutedProperties(Resource resource) throws IOException {
    String configString = SystemUtils.readFile(resource.getInputStream());
    configString = configString.replaceAll("\\$\\{au.org.arcs.dss.cache.dir}", ConfigManager.getConfigManagerInstance().getCacheDir().replaceAll("\\\\", "\\\\\\\\"));
    configString = configString.replaceAll("\\$\\{au.org.arcs.dss.cache.name}", ConfigManager.getConfigManagerInstance().getCacheName());

    InputStream is = new ByteArrayInputStream(configString.getBytes("UTF-8"));

    return is;
  }

  public static String readFile(InputStream input) {
    StringWriter writer = new StringWriter();
    char[] buffer = new char[1024];
    Reader reader = null;

    if (input != null) {
      try {
      reader = new BufferedReader( new InputStreamReader(input, "UTF-8"));
      int n = -1;

      while ((n = reader.read(buffer)) != -1) {
        writer.write(buffer, 0, n);
      }

      return writer.toString();

      } catch (Exception ex) {}
      finally {
        if (reader != null) {
          try {
            reader.close();
          } catch (Exception ex) {}
        }
      }
    }

    return "";
  }

  public static String getMainFileName(String string) {
    int index = 0;
    for (int i = string.length()-1; i >= 0; i--) {
      if (string.charAt(i) == '.') {
        index = i;
        break;
      }
    }

    return string.substring(0, index);
  }

  public static File getLoadedFile(String fileName, Date lastModified) {
    String fileMainNamefile = getMainFileName(fileName);

    File tempFolder = new File(ConfigManager.getConfigManagerInstance().getTempFileFolder());
    MatchFileFilter filter = new MatchFileFilter();
    filter.setFileName(fileMainNamefile);
    Date date = new Date();
    String tempFileName = date.getTime() + fileName;

    File[] matchedFiles = tempFolder.listFiles(filter);
    File file = null;

    if (matchedFiles != null && matchedFiles.length > 0) {
      long lastModifiedLong = matchedFiles[0].lastModified();
      int index = 0;

      for (int i = 1; i < matchedFiles.length; i++) {
        if (matchedFiles[i].lastModified() > lastModifiedLong ) {
          lastModifiedLong = matchedFiles[i].lastModified();
          matchedFiles[i-1].delete();
          index = i;
        } else {
          matchedFiles[i].delete();
        }
      }

      // Orignal file has been modified.
      if (lastModified.getTime() <= matchedFiles[index].lastModified()) {
        file = matchedFiles[0];
      }
    }

    if (file == null) {
      file = new File(tempFolder, PREFIX_TEMP + tempFileName);
    }

    matchedFiles = null;
    tempFolder = null;

    return file;
  }
}